﻿using System;
using System.ComponentModel;
using System.Linq;
using ProjectEuler.Linq;
using System.Text;

namespace ProjectEuler.Problems
{
    [EulerProblem(17, 21124)]
    [Description("How many letters would be needed to write all the numbers in words from 1 to 1000?")]
    internal sealed class Problem017 : EulerProblem
    {
        public override Object Solve()
        {
            return 
                Units[1].Length + 
                Thousand.Length + 
                (1).To(999).Sum(n => BritishStringLength(n));
        }
            
        private static Int32 BritishStringLength(Int32 n)
        {
            var result = 0;

            if (n >= 100)
            {
                var hundreds = (Int32)(n / 100);

                result += Units[hundreds].Length;
                result += Hundred.Length;

                n %= 100;

                if (n > 0)
                {
                    result += And.Length;
                }
            }

            if (n >= 20)
            {
                var tens = (Int32)(n / 10);

                result += Tens[tens].Length;
                n %= 10;
            }

            if (n > 0)
            {
                result += Units[n].Length;
            }

            return result;
        }

        private const String And = "and";
        private const String Hundred = "hundred";
        private const String Thousand = "thousand";

        private static readonly String[] Units = new[]
        {
            null,

            "one",
            "two",
            "three",
            "four",
            "five",
            "six",
            "seven",
            "eight",
            "nine",
            "ten",

            "eleven",
            "twelve",
            "thirteen",
            "fourteen",
            "fifteen",
            "sixteen",
            "seventeen",
            "eighteen",
            "nineteen",
            "twenty",
        };

        private static readonly String[] Tens = new[]
        {
            null, 

            "ten",
            "twenty",
            "thirty",
            "forty",
            "fifty",
            "sixty",
            "seventy",
            "eighty",
            "ninety",
        };
    }
}
